﻿/*****************************************************************************//*!
* file  : test.c
* creat : apleilx
* data  : 2017/03/02
*******************************************************************************/
#define   osObjectsCreat                                     // define objects in rtxapp module
#include "os_obj.h"                                          // RTOS object definitions
#include "mem_alloc.h"  
#include "sys_task.h"

void app_task_start(ULONG thread_input);
void app_task_idle(ULONG thread_input);
void app_task_stat(ULONG thread_input);

void task_console(ULONG thread_input);
void task_system(ULONG thread_input);
void modbus_task(ULONG thread_input);

void    tx_filex_application_define(void);
/*******************************************************************************
* @brief  任务定义
*******************************************************************************/
osThreadDef(thd_can, task_can, 10, 0, 256 * 2);
osThreadDef(thd_key, task_key, 10, 0, 256 * 2);


/*******************************************************************************
* @brief  任务创建
* \param[in] none
* \retval: none
*******************************************************************************/
int os_thread_init(void)
{
	/**************创建启动任务*********************/
	tx_thread_create(
		&os_obj.tcb_app_task_start,			//task tcb 
		"App Task Start",					//task name
		app_task_start,						//task entry
		0,									//task argv
		&os_obj.stk_app_task_start[0],		//task stack
		sizeof(os_obj.stk_app_task_start),	//stack size 
		APP_CFG_TASK_START_PRIO,			//task priority
		APP_CFG_TASK_START_PRIO,			//priority force sw
		TX_NO_TIME_SLICE,					//time slice off
		TX_AUTO_START);						//auto start

	return(0);
}

/*----------------------------------------------------------------------------
 *  creat thread object
 *---------------------------------------------------------------------------*/
int os_thread_creat(void)
{
	os_obj_creat();

	/**************创建状态任务*********************/
	tx_thread_create(&os_obj.tcb_task_stat,	//task tcb  
		"App Task STAT",              		//task name
		app_task_stat,                 		//task entry
		0,                           		//task argv
		&os_obj.stk_task_stat[0],			//task stack
		sizeof(os_obj.stk_task_stat),		//stack size 
		APP_CFG_TASK_STAT_PRIO,				//task priority
		APP_CFG_TASK_STAT_PRIO,				//priority force sw
		TX_NO_TIME_SLICE,					//time slice off
		TX_AUTO_START);						//auto start


	/**************创建空闲任务*********************/
	tx_thread_create(&os_obj.tcb_task_idle,	//task tcb  
		"App Task IDLE",					//task name
		app_task_idle,						//task entry
		0,									//task argv
		&os_obj.stk_task_idle[0],			//task stack
		sizeof(os_obj.stk_task_idle),		//stack size 
		APP_CFG_TASK_IDLE_PRIO,				//task priority
		APP_CFG_TASK_IDLE_PRIO,				//priority force sw
		TX_NO_TIME_SLICE,					//time slice off
		TX_AUTO_START);						//auto start


	/**************创建控制台任务*********************/
	tx_thread_create(&os_obj.tcb_task_console,        //task tcb  
		"App Task console",              //task name
		task_console,                  //task entry
		0,                           //task argv
		&os_obj.stk_task_console[0],//task stack
		sizeof(os_obj.stk_task_console),   //stack size 
		APP_CFG_TASK_CONSOLE_PRIO,       //task priority
		APP_CFG_TASK_CONSOLE_PRIO,       //priority force sw
		TX_NO_TIME_SLICE,            //time slice off
		TX_AUTO_START);              //auto start 

	os_obj.tid_console = &os_obj.tcb_task_console;

	/*----------------- creat system task ---------------*/
	tx_thread_create(&os_obj.tcb_task_system,        //task tcb  
		"App Task system",              //task name
		task_system,                  //task entry
		0,                           //task argv
		&os_obj.stk_task_system[0],//task stack
		sizeof(os_obj.stk_task_system),   //stack size 
		APP_CFG_TASK_SYSTEM_PRIO,       //task priority
		APP_CFG_TASK_SYSTEM_PRIO,       //priority force sw
		TX_NO_TIME_SLICE,            //time slice off
		TX_AUTO_START);              //auto start

	os_obj.tid_system = &os_obj.tcb_task_system;


	/*----------------- creat mb task -----------------*/
	tx_thread_create(&os_obj.tcb_task_modbus,        //task tcb  
		"modbus tst",              //task name
		modbus_task,                  //task entry
		0,                           //task argv
		&os_obj.stk_task_modbus[0],//task stack
		sizeof(os_obj.stk_task_modbus),   //stack size 
		APP_CFG_TASK_MODBUS_PRIO,       //task priority
		APP_CFG_TASK_MODBUS_PRIO,       //priority force sw
		TX_NO_TIME_SLICE,            //time slice off
		TX_AUTO_START);              //auto start

	os_obj.tid_modbus = &os_obj.tcb_task_modbus;

	osThreadCreate(osThread(thd_can), "can");
	osThreadCreate(osThread(thd_key), "lcm");

	tx_filex_application_define();

	return 0;
}

/*----------------------------------------------------------------------------
 *  creat os object
 *---------------------------------------------------------------------------*/
int os_obj_creat(void)
{
	/* creat mutex */
	tx_mutex_create(&os_obj.mutex_printf,
		"mutex_printf",
		TX_NO_INHERIT);  //no prio 
	os_obj.mid_printf = &os_obj.mutex_printf;

	tx_mutex_create(&os_obj.mutex_common,
		"mutex_common",
		TX_NO_INHERIT);  //no prio 
	os_obj.mid_common = &os_obj.mutex_common;

	/* creat quene */
	tx_queue_create(&os_obj.quene_tst,          //Pointer to queue control block
		"tst quene",                //Pointer to queue name
		1,                          //Size of each queue message (Number of ULONG)
		os_obj.quene_tst_mem,       //Starting address of the queue area
		sizeof(os_obj.quene_tst_mem));      //Number of bytes in the queue
	os_obj.qid_tst = &os_obj.quene_tst;

	/* creat event */

	tx_event_flags_create(&os_obj.event_mb,
		"event mb");
	os_obj.eid_mb = &os_obj.event_mb;

	tx_event_flags_create(&os_obj.event_can,
		"event can");
	os_obj.eid_can = &os_obj.event_can;

	/* creat semaphore */
	tx_semaphore_create(&os_obj.sem_tst,
		"sem tst",
		1);              //init val  
	os_obj.sid_tst = &os_obj.sem_tst;

	os_mem_pool_creat();
	
	return(0);
}

/*------------------------------------------------------------------------------
 *  task stack used
 *----------------------------------------------------------------------------*/
int32_t os_task_stk_used(osThreadId tid)
{
	uint32_t start,end, unused;
	
	start = (uint32_t)tid->tx_thread_stack_start;
	end = (uint32_t)tid->tx_thread_stack_end;
	
	unused = start;
	
	while(inpw(unused) == 0xEFEFEFEF && inpw(unused+4) == 0xEFEFEFEF)
	{
		unused += 8;
	}
	
	return ((end+1) - unused);
}

/*------------------------------------------------------------------------------
 *  task info
 *----------------------------------------------------------------------------*/
void tx_task_info(void)
{
	extern TX_THREAD *_tx_thread_created_ptr;
	TX_THREAD *tid = _tx_thread_created_ptr;

    dbg_print("===========================================================\n");
	dbg_print("==================CPU USAGE : %5.2f%% ======================\n",
			  sys_st.f_cpu_usage);
    dbg_print("===========================================================\n");
	
	do
	{
		int32_t stk_used = os_task_stk_used(tid);
		
		dbg_print("prio: %-3d, run count: %-8d :: stack (%08x - %08x), " \
				  "size %5d, used %5d # %-3d%% :: %s\n",
			tid->tx_thread_priority,
			tid->tx_thread_run_count,
			tid->tx_thread_stack_start,
			tid->tx_thread_stack_end,
			tid->tx_thread_stack_size,
			stk_used,
			stk_used * 100 / tid->tx_thread_stack_size,
			tid->tx_thread_name);

		tid = tid->tx_thread_created_next;
	} while (tid && tid != _tx_thread_created_ptr);
}
